/*
 * 
 *
 * Authors: Soeren Gebbert, soeren.gebbert@vti.bund.de
 *          Axel Don, axel.don@vti.bund.de
 *
 * Copyright:
 *
 * Johann Heinrich von Thünen-Institut
 * Institut für Agrarrelevante Klimaforschung
 *
 * Phone: +49 (0)531 596 2601
 *
 * Fax:+49 (0)531 596 2699
 *
 * Mail: ak@vti.bund.de
 *
 * Bundesallee 50
 * 38116 Braunschweig
 * Germany
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <iostream>
#include <sstream>
#include <string>
#include <fstream>
#include "initial_parameters.h"
#include "permutation_event.h"
using namespace std;

/* -------------------------------------------------------------------------- */
initial_parameters::initial_parameters() {
    this->number_of_timesteps = 10000;
    this->max_num_carb_particle = 100000;
    this->num_micr_cluster = 1000;
    this->width = 100.0;
    this->height = 100.0;
    this->depth = -100.0;
    this->depth_steps = 10;
    this->max_carb_depth = 0.0;
    this->max_micr_depth = this->depth;
    this->min_initial_micr_mass = 1.0;
    this->max_initial_micr_mass = 1.0;
    this->porosity = 0.15;
    this->seed = 1;
    this->output_step = 50;
    this->micr_filename = "micr.csv";
    this->carb_filename = "carb.csv";
    this->profile_filename = "prof.csv";
    this->run_filename = "run.csv";
    this->search_method = "ANN";    
    this->constant_radius = 0;

}

/* -------------------------------------------------------------------------- */
void initial_parameters::read(char *filename) {
    char buff[1024];
    size_t pos;

    ifstream input(filename, ifstream::in);

    if (input) {
        while (input.getline(buff, 1024)) {

            string line(buff);
            string sub;
            /* Ignore lines with a leading #, its a comment */
            if (line.find("#") != string::npos)
                continue;

            if (line.find("number_of_timesteps") != string::npos) {
                pos = line.find("=");
                if (pos != string::npos) {
                    sub = line.substr(pos + 1);
                    stringstream ss(sub);
                    ss >> this->number_of_timesteps;
                }
            }
            if (line.find("max_num_carb_particles") != string::npos) {
                pos = line.find("=");
                if (pos != string::npos) {
                    sub = line.substr(pos + 1);
                    stringstream ss(sub);
                    ss >> this->max_num_carb_particle;
                }
            }
            if (line.find("num_micr_cluster") != string::npos) {
                pos = line.find("=");
                if (pos != string::npos) {
                    sub = line.substr(pos + 1);
                    stringstream ss(sub);
                    ss >> this->num_micr_cluster;
                }
            }
            if (line.find("width") != string::npos) {
                pos = line.find("=");
                if (pos != string::npos) {
                    sub = line.substr(pos + 1);
                    stringstream ss(sub);
                    ss >> this->width;
                }
            }
            if (line.find("height") != string::npos) {
                pos = line.find("=");
                if (pos != string::npos) {
                    sub = line.substr(pos + 1);
                    stringstream ss(sub);
                    ss >> this->height;
                }
            }
            if (line.find("depth_steps") != string::npos) {
                pos = line.find("=");
                if (pos != string::npos) {
                    sub = line.substr(pos + 1);
                    stringstream ss(sub);
                    ss >> this->depth_steps;
                }
            }
            if (line.find("max_carb_depth") != string::npos) {
                pos = line.find("=");
                if (pos != string::npos) {
                    sub = line.substr(pos + 1);
                    stringstream ss(sub);
                    ss >> this->max_carb_depth;
                }
            }
            if (line.find("max_micr_depth") != string::npos) {
                pos = line.find("=");
                if (pos != string::npos) {
                    sub = line.substr(pos + 1);
                    stringstream ss(sub);
                    ss >> this->max_micr_depth;
                }
            }
            if (line.find("min_initial_micr_mass") != string::npos) {
                pos = line.find("=");
                if (pos != string::npos) {
                    sub = line.substr(pos + 1);
                    stringstream ss(sub);
                    ss >> this->min_initial_micr_mass;
                }
            }
            if (line.find("max_initial_micr_mass") != string::npos) {
                pos = line.find("=");
                if (pos != string::npos) {
                    sub = line.substr(pos + 1);
                    stringstream ss(sub);
                    ss >> this->max_initial_micr_mass;
                }
            }
            if (line.find("seed") != string::npos) {
                pos = line.find("=");
                if (pos != string::npos) {
                    sub = line.substr(pos + 1);
                    stringstream ss(sub);
                    ss >> this->seed;
                }
            }
            if (line.find("output_step") != string::npos) {
                pos = line.find("=");
                if (pos != string::npos) {
                    sub = line.substr(pos + 1);
                    stringstream ss(sub);
                    ss >> this->output_step;
                }
            }
            if (line.find("micr_filename") != string::npos) {
                pos = line.find("=");
                if (pos != string::npos) {
                    sub = line.substr(pos + 1);
                    stringstream ss(sub);
                    ss >> this->micr_filename;
                }
            }
            if (line.find("carb_filename") != string::npos) {
                pos = line.find("=");
                if (pos != string::npos) {
                    sub = line.substr(pos + 1);
                    stringstream ss(sub);
                    ss >> this->carb_filename;
                }
            }
            if (line.find("profile_filename") != string::npos) {
                pos = line.find("=");
                if (pos != string::npos) {
                    sub = line.substr(pos + 1);
                    stringstream ss(sub);
                    ss >> this->profile_filename;
                }
            }
            if (line.find("run_filename") != string::npos) {
                pos = line.find("=");
                if (pos != string::npos) {
                    sub = line.substr(pos + 1);
                    stringstream ss(sub);
                    ss >> this->run_filename;
                }
            }
            if (line.find("search_method") != string::npos) {
                pos = line.find("=");
                if (pos != string::npos) {
                    sub = line.substr(pos + 1);
                    stringstream ss(sub);
                    ss >> this->search_method;
                }
            }
            if (line.find("porosity") != string::npos) {
                pos = line.find("=");
                if (pos != string::npos) {
                    sub = line.substr(pos + 1);
                    stringstream ss(sub);
                    ss >> this->porosity;
                }
            }
            if (line.find("constant_radius") != string::npos) {
                pos = line.find("=");
                if (pos != string::npos) {
                    sub = line.substr(pos + 1);
                    stringstream ss(sub);
                    ss >> this->constant_radius;
                }
            }
            if (line.find("event") != string::npos) {
                string event_id;
                string input_file;
                pos = line.find("=");
                if (pos != string::npos) {
                    sub = line.substr(pos + 1);
                    stringstream ss(sub);
                    ss >> event_id;
                    ss >> input_file;
                    if(event_id.find("permutation") != string::npos) {
                        cout << "Register " << event_id << " event" << endl;
                        permutation_event *event = new permutation_event(input_file);
                        this->events.push_back(event);
                    }
                }
            }
        }
    } else {
        cerr << "Unable to open or read initial parameter file " << filename << endl;
    }

    input.close();
}